package com.livestocksolutions.ui;

import com.livestocksolutions.R;
import com.livestocksolutions.intent.BaseActivity;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

/* -- Version History --
 *  1.0 : 08 September 2012 - Initial version.
 */

/**
 * Base class to which other ArrayAdapters can extend if there are similar underlying methods
 * that can be used.
 * @author Adam Parr
 * @version 1.0
 * 
 * @.modified 18 October 2012
 */
public class BaseArrayAdapter extends ArrayAdapter<String[]>{
	/**
	 * Size of the allowable array passed
	 */
	public static final int SIZE = 0;
	
	/**
	 * The Format of the String that is expected a Date to be displayed in.<br>
	 * Where the length is long.
	 */
	public static String DATEFORMATSTRINGLONG;
	/**
	 * The Format of the String that is expected a Date to be displayed in.<br>
	 * Where the length is short.
	 */
	public static String DATEFORMATSTRINGSHORT;
	
	/**
	 * The root View in which all objects related will be accessable from.
	 */
	protected View root;
	/**
	 * A flag that stores whether or not the current state of the Object is valid to save.<br>
	 * <tt>true</tt> The structure is valid and can be saved. <tt>false</tt> The structure
	 * is invalid, do not save this object while it is in this state. Alert the user to
	 * the fact this is currently invalid.
	 */
	protected boolean valid = true;
	/**
	 * The current context
	 */	
	protected BaseActivity context;
	/**
	 * A 2D String Array.
	 *   First Dimension refers to each instance of an Object to be shown
	 *   Second Dimension refers to the data to be displayed for this Object
	 */
	protected String[][] values;
	/**
	 * Stores the Resource TextView id to inflate when {@link #getView(int, View, ViewGroup)} is called.
	 */
	protected int textViewResourceId=0;
	
	/**
	 * Constructor
	 * @param context The current context.
	 * @param values The Contacts to represent in the ListView.
	 */
	public BaseArrayAdapter(BaseActivity context, String[][] values) {
		super(context, android.R.layout.simple_list_item_1, values);
		this.context = context;
		this.values = values;
		if(DATEFORMATSTRINGLONG==null){
			DATEFORMATSTRINGLONG = context.getDateFormatLong();
			DATEFORMATSTRINGSHORT = context.getDateFormat();
		}
	}
	
	/**
	 * Constructor
	 * @param context The current context.
	 * @param resourceId The View to create
	 * @param values The Contacts to represent in the ListView.
	 */
	protected BaseArrayAdapter(BaseActivity context, int resourceId, String[][] values){
		super(context, resourceId, values);
		this.context = context;
		this.values = values;
		
		if(DATEFORMATSTRINGLONG==null){
			DATEFORMATSTRINGLONG = context.getDateFormatLong();
			DATEFORMATSTRINGSHORT = context.getDateFormat();
		}
	}
	
	/**
	 * @see #setView(int, View, ViewGroup)
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		return setView(position,convertView,parent);
	}
	
	/**
     * Get a View that displays the data at the specified position in the data set. You can either
     * create a View manually or inflate it from an XML layout file. When the View is inflated, the
     * parent View (GridView, ListView...) will apply default layout parameters unless you use
     * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
     * to specify a root view and to prevent attachment to the root.
     * 
     * @param position The position of the item within the adapter's data set of the item whose view
     *        we want.
     * @param convertView The old view to reuse, if possible. Note: You should check that this view
     *        is non-null and of an appropriate type before using. If it is not possible to convert
     *        this view to display the correct data, this method can create a new view.
     *        Heterogeneous lists can specify their number of view types, so that this View is
     *        always of the right type (see {@link android.widget.BaseAdapter#getViewTypeCount()} and
     *        {@link android.widget.BaseAdapter#getItemViewType(int)}).
     * @param parent The parent that this view will eventually be attached to
     * @return A View corresponding to the data at the specified position.
     */
	public final View setView(int position, View convertView, ViewGroup parent) {
		View rowView = super.getView(position, convertView, parent);
		rowView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(textViewResourceId, parent, false);
		rowView.setId(position);
		
		if(position%2==1){
			rowView.setBackgroundResource(R.drawable.rounded_light_1);
		}else{
			rowView.setBackgroundResource(R.drawable.rounded_light_2);
		}
		
		rowView.setMinimumHeight(context.getResources().getDimensionPixelSize(R.dimen.list_item_minHeight));
		
		return rowView;
	}
	
	@Override
	public void add(String[] newItem){
		String[][] orig = values;
		values = new String[orig.length+1][];
		
		for(int x = 0; x < orig.length; x++){
			values[x] = orig[x];
		}
		values[orig.length] = newItem;

		notifyDataSetChanged();
	}
	
	@Override
	public void remove(String[] contact){
		String[][] orig = values;
		values = new String[orig.length-1][0];
		
		int y=0;
		try{
			for(int x = 0; x < orig.length; x++){
				boolean valid = true;
				for(int a = 0; a < orig[x].length; a++){
					if(	!(orig[x][a]==null && contact[a]==null) && ((orig[x][a]==null && contact[a]!=null) || (orig[x][a]!=null && contact[a]==null) || !orig[x][a].equals(contact[a]))){
						valid=false;
						break;
					}
				}
				if(!valid){
					values[y] = orig[x];
					y++;
				}
			}
		}catch(Exception e){
			// If we can't make a match an array index out of bounds exception will occur.
			// Set the original array back to the values.
			e.printStackTrace();
			values = orig;
		}
		
		notifyDataSetChanged();
	}
	
	@Override
	public int getCount(){
		return values.length;
	}
	
	@Override
	public String[] getItem(int position){
		return values[position];
	}
	
	/**
	 * Replace an item in this list with fresh values.
	 * @param value the new data to replace the old data with.
	 * @param position the position to replace the data.
	 */
	public void replace(String[] value, int position){
		values[position]=value;
	}
	
	/**
	 * Get the array of values stored in this data set.
	 * @return The data set of values for this ArrayAdapter.
	 */
	public String[][] get() {
		return values;
	}
	
	/**
	 * Set the TextView id to inflate when creating this list
	 * @param textViewResourceId the TextView id to inflate when {@link #getView(int, View, ViewGroup)} is called.
	 */
	public void setView(int textViewResourceId){
		this.textViewResourceId=textViewResourceId;
	}
	
	/**
	 * Change the id of the View with the id given in <tt>oldId</tt> and change it to the value given in <tt>newId</tt>.
	 * @param newId The new ID to give to the View with the <tt>oldId</tt>.
	 * @param oldId The View with this id to change.
	 * @return The View that has just had it's id changed.
	 */
	public View setId(int newId, int oldId){
		View rowView;
		if(root != null){
			rowView = root.findViewById(oldId);
		}else{
			rowView = context.findViewById(oldId);
		}
		rowView.setId(newId);
		return rowView;
	}
	
	/**
	 * Set the View at which all items in this group will be accessible.
	 * @param view The view which will be the parent of the items.
	 */
	public void setRoot(View view){
		root = view;
	}
	
	/**
	 * Check to see if this Object can be allowed to be saved in it's current state.
	 * @return <tt>true</tt> if the object is allowed to be saved. <tt>false</tt>
	 * if this object should not be saved.
	 */
	public boolean isValid(){
		return valid;
	}
}